<?php
//if not a real page (nobody called us here, just user trying to hack
if ((!isset($_SESSION['realpage']))
 || ($_SESSION['realpage'] == false))
 {
 	require './hack.php';
 	die(" ");
 }

 
// includes
require_once "./class.DBConnection.php";
require_once "./class.user.php";
require_once "./class.Group.php";

class GeneralServices {

	public function getErrors()
	{
		return $this->conn->getError();
	}
	public function getGroupUsers($gid)  
	{
		if (!is_numeric($gid)) 
		{
		   	return array();
		}
		return $this->conn->getGroupUsers($gid);  
	}
	
	public function getGroupWBUsers($gid)
	{
		if (!is_numeric($gid))
		{
			return array();
		}
		return $this->conn->getGroupWBUsers($gid);
	}
	
	public function getUserswall($myUid,$uid)
	{
		if (!is_numeric($uid) || !is_numeric($myUid)) 
		{
		   	return array();
		}
		$tmpGid= $this->conn->getUserswall($uid);
		return $this->conn->getGroup($myUid,$tmpGid) ;  
	}
	
	public function getUser($uid)
 	{
 		if (!is_numeric($uid))
 			return  null;
 		
 		return $this->conn->getUser($uid);
 	}
 	
	public function getRandomFriends($uid,$maxFriends)
    { 
    	if (!is_numeric($uid) || !is_numeric($maxFriends) ) return false;
    	return $this->conn->getRandomFriends($uid,$maxFriends);
    }  
    
    public function searchFriend($user,$criteria,$limit)  
	{
		if (!is_numeric($user) || !is_numeric($limit) ) return false;
    	return $this->conn->searchFriend($user,$criteria,$limit)  ;
	}
	
	public function getUserRealFriends($user,$limit,$downpour)  
	{
		if (!is_numeric($user) || !is_numeric($limit) || !is_numeric($downpour) ) return false;
    	return $this->conn->getUserFriends($user,$limit,$downpour,'M');	
	}
	
	public function getUserWannabeFriends($user,$limit,$downpour)  
	{
		if (!is_numeric($user) || !is_numeric($limit) || !is_numeric($downpour) ) return false;
    	return $this->conn->getUserFriends($user,$limit,$downpour,'P');	
	}

	public function getUserInvitedFriends($user,$limit,$downpour)  
	{
		if (!is_numeric($user) || !is_numeric($limit) || !is_numeric($downpour) ) return false;
    	return $this->conn->getUserFriends($user,$limit,$downpour,'I');	
	}
	public function getUserBannedFriends($user,$limit,$downpour)  
	{
		if (!is_numeric($user) || !is_numeric($limit) || !is_numeric($downpour) ) return false;
    	return $this->conn->getUserFriends($user,$limit,$downpour,'D');	
	}
	public function sendMessage($uid,$friend,$content)
 	{
 		if (!is_numeric($uid) || !is_numeric($friend)) return false;
 	 	
 		return $this->conn->sendMessage($uid,$friend,$content);
 	}

	public function getThread($uid,$friend,$limit,$downpour)
 	{
 		if (!is_numeric($uid) || !is_numeric($friend) || !is_numeric($limit)) return false;
 	
   		return $this->arrayReverse($this->conn->getThread($uid,$friend,$limit,$downpour));	 	
 	}
 	
	public function getUserMessages($uid,$limit,$downpour)
 	{
 		//TODO: test	
 		if (!is_numeric($uid)) return false;
 
   		return $this->conn->getUserMessages($uid,$limit,$downpour);	 	
 	}
	public function showTalkback($uid,$tbid)
	{
		
		if ((!is_numeric($uid)) || (!is_numeric($tbid))) 
		{
		   return false;
		}
		return $this->conn->setTalkbackVisibility($uid,$tbid,1);
	}// end showTalkback
	
	public function hideTalkback($uid,$tbid)
	{
		
		if ((!is_numeric($uid)) || (!is_numeric($tbid))) 
		{
		   return false;
		}
		return $this->conn->setTalkbackVisibility($uid,$tbid,0);
	}// end hideTalkback
	
	public function showPost($uid,$pid)
	{
		
		if ((!is_numeric($uid)) || (!is_numeric($pid))) 
		{
		   return false;
		}
		return $this->conn->setPostVisibility($uid,$pid,1);
	}// end showPost
	
	public function hidePost($uid,$pid)
	{
		if ((!is_numeric($uid)) || (!is_numeric($pid))) 
		{
		   return false;
		}
		return $this->conn->setPostVisibility($uid,$pid,0);
	}// end hidePost
	
	public function publishPost($user,$gid,$content,$topic)
	{
						
		if (!is_numeric($user) || !is_numeric($gid)) 
		{
		   	return false;
		}
		
		return $this->conn->publishPost($user,$gid,$content,$topic);	
	}
	
	public function getGroup($user,$groupId) 
	{
		return  $this->conn->getGroup($user,$groupId);
	}
	public  function getUserGroups($user,$limit,$downpour)  
	{
		if ((!is_numeric($user)) ||(!is_numeric($limit)))
   		{
   			return false;
   		}
   		if (!isset($downpour) || !is_numeric($downpour))
   		{
   			$downpour=0;
   		}
   		
   		return $this->conn->getUserGroups($user,$limit,$downpour)  ;
	}
	
	public function getRandomGroups($user,$maxGroups) 
	{
		if ((!is_numeric($maxGroups)) ||(intval($maxGroups) > 50))
   		{
   			$maxGroups = 50;
   		}
   		
   		return $this->conn->getRandomGroups($user,$maxGroups);
	}
	
 	public function createGroup($gname,$gdesc,$visibility,$ownerUid)
 	{ 
 		if(!is_numeric($ownerUid) || intval($ownerUid) == 0 )
 		{
 		 	return false;
 		}
 		return $this->conn->createGroup($gname,$gdesc,$visibility,0,$ownerUid);
 	}
 	
	//criteria = part of the name of the group
	public function searchGroup($user,$criteria,$limit)  
	{
		if (!is_numeric($user)) 
   		{
   			return array();
   		}
   		return $this->conn->searchGroup($user,$criteria,$limit);	
	}
	
	public function applyForGroup($user,$groupId) 
	{ 
		if ((!is_numeric($groupId)) || (!is_numeric($user)))
			return false;
		$rel = 	$this->conn->getRelationType($groupId,$user);
			
		if ($rel == 'N') // user asked without invite
			return $this->conn->addRelation($groupId,$user,'P');
			
		if ($rel == 'I') // invited by owener, user accept
			return $this->conn->addRelation($groupId,$user,'M');
			
		if ($rel == 'L') // wants to get in after leaving
			return $this->conn->addRelation($groupId,$user,'P');
				
		return false;
	}
	
	public function friend($user,$invitedFriend) 
	{ 
		if ((!is_numeric($user)) || (!is_numeric($invitedFriend)))
			return false;
			
		$hisgrp = $this->getUserswall($user, $invitedFriend);
		$mygrp  = $this->getUserswall($user, $user);
		
		//$currRelation = $this->conn->getRelationType($grp,user);
		
		$stats = $this->applyForGroup($user, $hisgrp->gid);
		$stats = $stats && $this->inviteUserToGroup($user, $mygrp->gid,$invitedFriend);
		
		return $stats;
	}
	
	public function unfriend($user,$friend) 
	{ 
		if ((!is_numeric($user)) || (!is_numeric($friend)))
			return false;
			
		$hisgrp = $this->getUserswall($user, $friend);
		$mygrp  = $this->getUserswall($user, $user);
		
		//$currRelation = $this->conn->getRelationType($grp,user);
		
		$stats = $this->leaveGroup($user, $hisgrp->gid);
		$stats = $stats && $this->leaveGroup($friend, $mygrp->gid);
		
		return $stats;
	}
	
	public function getRelationType($user,$groupId) 
	{
		if ((!is_numeric($groupId)) || (!is_numeric($user)))
			return false;
			
		return $this->conn->getRelationType($groupId,$user);
	}
	
	public function leaveGroup($user,$groupId) 
	{ 
		if ((!is_numeric($groupId)) || (!is_numeric($user)))
			return false;
			
		$tmp  = $this->conn->getRelationType($groupId,$user);
		
		if ( ($tmp!= 'N') && ($tmp !='O'))
			return $this->conn->addRelation($groupId,$user,'L');
			
		return false;
	}
	public function banFromGroup($user,$groupId,$member) 
	{ 
		if ((!is_numeric($groupId)) || (!is_numeric($user)) || (!is_numeric($member)))
			return false;

		if ($this->conn->getRelationType($groupId,$user) != 'O') return false;
		
		$tmp  = $this->conn->getRelationType($groupId,$member);
		
		// if he's not an owner, deny access (ban)
		if ($tmp !='O')
			return $this->conn->addRelation($groupId,$member,'D');
			
		return false;
	}
	
	public function inviteUserToGroup($user,$groupId,$invitee) 
	{//TODO: test
		if ((!is_numeric($groupId)) || (!is_numeric($user)) || (!is_numeric($invitee)))
			return false;

		if ($this->conn->getRelationType($groupId,$user) != 'O') return false;
		
		$tmp  = $this->conn->getRelationType($groupId,$invitee);
		
		if ($tmp == 'P') //if he's waiting, then approve
		 	return $this->conn->addRelation($groupId,$invitee,'M');
		if ($tmp== 'L') //here for debug
			return $this->conn->addRelation($groupId,$invitee,'I');
			 	
		 	//if he's not a member, invite
		if ( ($tmp!= 'M') && ($tmp !='O'))
			return $this->conn->addRelation($groupId,$invitee,'I');
		
		return false;
	}
	
	
	public function login($username,$password) 
	{ 
		
		$usr				     = $this->conn->login($username,$password);
		$_SESSION['userObj']	 = $usr;
		
		return $usr;
	}
	public function publishTalkback($user,$pid,$content)
	{
		if ((!is_numeric($user)) || (!is_numeric($pid)))
			return false;
		return $this->conn->publishTalkback($user,$pid,$content);
	}
	
	public function register($username,$password,$firstname,$lastname,$birthday,$about,$email)
	{
		//verify e-mail.
		if (!filter_var($email, FILTER_VALIDATE_EMAIL))
			return false;
			
		// check if usr is trying for a handle that already exists
		if (!$this->isHandleAvailable($username))
		{
			return null;
		}
			
		// validate date
		//case 'DD-MM-YYYY':
        //case 'DD/MM/YYYY':
		list( $d, $m, $y ) = preg_split( '/[-\.\/ ]/', $birthday );
		
		if (!checkdate( $m, $d, $y ))
			return false;
			
		//try and register him
		$usr				 = $this->conn->register($username,$password,$firstname,$lastname,$birthday,$about,$email);
		
		if($usr != false)
		{
			$_SESSION['userObj']	 = $usr;
		}
		return $usr;  
		
	}
	
	public function genRandomString() {
		return $this->conn->genRandomString();
	}
	
	public function isHandleAvailable($handle)
	{
		//check if handle is available
		return $this->conn->isHandleAvailable($handle);
	}
	public function updateUserInfo($fname, $lname, $email, $bday, $about, $uid)
	{
		$res = $this->conn->UpdateUserDetails($fname, $lname, $email, $bday, $about, $uid);		
		if ($res == true)
		{
			return true;
		}
		return false;
	}
	
	public function getGroupPosts($group,$limit,$downpour,$uid)  
	{
		if (!is_numeric($group) || !is_numeric($uid) ) 
		{
		   	return array();
		}
		if (!is_numeric($limit)) 
		{
		   	$limit = 15;
		}
		if (!isset($downpour) || !is_numeric($downpour)) 
		{
		   	$limit = 0;
		}
		
		$visibility=1; // only visible
		if ('O' == $this->conn->getRelationType($group,$uid)) 
		{
			$visibility = 0; //owner, show banned material
		}
		return $this->conn->getGroupPosts($group,$limit,$downpour,$visibility);
	}
	
	
	public function getFriends($userId) 
	{
		return array(new User()); 
	}
	
	public function getMutualFriends($refSession,$user2)
	{
		return new User(); // return array
	}
	
	
	//todo Continue
	public function getMessages($refSession,$user2)
	{
		return new Message(); // return array
	}
	
	
	public function getPostTalkbacks($pid,$limit,$downpour,$uid)  
	{
		$visibility=1; // only visible
		if ('O' == $this->conn->getRelationType($pid,$uid)) 
		{
			$visibility = 0; //owner, show banned material
		}
		return $this->conn->getPostTalkbacks($pid,$limit,$downpour,$visibility);
	}
	
	public function RenderGroupName($num)
	{
		return $num;
	}
	
	public function RenderFriendName($num)
	{
		return $num;
	}
	
	// singleton
	public static function getService() 
	{
		// singleton
		if (GeneralServices::$instance == null)
		{
			GeneralServices::$instance			 = new GeneralServices();
			GeneralServices::$instance->conn	     = DBConnection::getConn();
		}	
		
		return GeneralServices::$instance;
	}
		
	public function arrayReverse($arr)
	{
	    $c = count($arr);
	    $narr = array();
	    for($i=0;$i<$c;)
	    {
	        $narr[$i] = $arr[$c-$i-1];
	        $i++;
	    }
	   return  $narr;	   
	}
	
	// singleton
	private static $instance	 = null;
	//property conn = connection to DB
	private $conn				 = null;
	
	
	
}


?>